<template>
  <view class="qr-container" :style="'height:'+canvasSize+';width:'+canvasSize+';'">
    <image v-if="!canvasMode" :src="imgSrc" class="full-w-h" :show-menu-by-longpress="showMenuByLongpress"
      mode="aspectFill" />
    <!-- 主绘制区 -->
    <canvas id="qr-main-container" class="qr-canvas"
      :class="!canvasMode && 'hide-canvas'"
      :style="'height: '+canvasSize+';width: '+canvasSize+';'" type="2d"></canvas>
  </view>
</template>
<script>
import { AwesomeQR } from "./lib/awesome-qr";
import { getPxFromStringOrNumber, getRpxFromStringOrNumber, resetCanvasHeighAndWidth } from "./lib/utils";


export default {
  props: {
    // 要扫出来的内容
    text: {
      type: String,
      required: true
    },
    // canvas大小
    size: {
      type: [Number, String],
      default: '200rpx'
    },
    // 是否以canvas展示二维码
    canvasMode: {
      type: Boolean,
      value: false
    },
    // canvasMode === false情况下，是否支持长按二维码展示菜单
    showMenuByLongpress: {
      type: Boolean,
      default: true
    },
    margin: {
      type: [Number, String],
      default: 0
    },
    correctLevel: {
      type: Number,
      default: 0
    },
    maskPattern: {
      type: [Number, null],
      default: null
    },
    version: {
      type: [Number, null],
      default: null
    },
    components: {
      type: Object,
      default() {
        return {}
      }
    },
    colorDark: {
      type: String,
      default: "#000000"
    },
    colorLight: {
      type: String,
      default: "#FFFFFF"
    },
    autoColor: {
      type: Boolean,
      default: false
    },
    backgroundImage: {
      type: String,
      default: undefined
    },
    // 背景图上掩膜的颜色
    backgroundDimming: {
      type: String,
      default: "rgba(0,0,0,0)"
    },
    // 如果有margin的话是否展示白色的边
    whiteMargin: {
      type: [Boolean, String],
      default: false
    },
    // logo地址
    logoImage: {
      type: String,
      value: undefined
    },
    // logo占整个二维码比例
    logoScale: {
      type: Number,
      default: 0.2
    },
    // logo外边距大小
    logoMargin: {
      type: [Number, String],
      default: 20
    },
    // logo圆角
    logoCornerRadius: {
      type: Number,
      default: 20
    },
    // 每个二维码块的比例
    dotScale: {
      type: Number,
      default: 1
    }
  },  
  data() {
    return {
      // 图片src
      imgSrc: '',
      // canvas大小: 默认200px
      canvasSize: '200px'
    }
  },
  watch: {
    size: {
      handler(newVal) {
        this.canvasSize = getPxFromStringOrNumber(newVal) + "px"

        // console.log(this.canvasSize, 11);
      },
      immediate: true
    },
    totalWatch:{
      handler() {
        this.render()
      },
      immediate: true
    }
  },
  computed: {
    // 计算出多个属性，用于监视。也可用$watch
    totalWatch() {
      return [
        this.text,this.size,this.canvasMode,this.showMenuByLongpress,
        this.margin,this.correctLevel,this.maskPattern,this.version,
        this.components,this.colorDark,this.colorLight,this.autoColor,
        this.backgroundImage,this.whiteMargin,this.logoImage,this.logoScale,
        this.logoMargin,this.logoCornerRadius,this.dotScale
      ]
    }
  },
  methods: {
    async render() {
      const {
          text, // 内容
          size, // 宽高
          margin, // margin
          colorDark, // 二维码颜色
          colorLight, // 二维码背景色
          maskPattern, // 二维码自定义掩码
          backgroundDimming, // 背景图上掩膜的颜色
          logoScale, // 二维码图片占整个区域的百分比
          correctLevel, // 纠错级别
          logoMargin, // logo的margin
          logoCornerRadius, // logo的圆角
          dotScale, // 每块二维码点的大小
          backgroundImage, // 二维码大背景图
          logoImage, // logo图片
          whiteMargin, // 如果有margin是否展示白边
          autoColor, // 是否自动根据背景图配置二维码颜色
          components, // 二维码中控制组件的选项。区域比列，半透明保护
          version, // 二维码版本
      } = this

      // 转为px
      let pxSize = getPxFromStringOrNumber(size);
      const [qrMainContainer] = await this.getCanvasAndContext(pxSize);

      let option = {
        text,
        size: pxSize,
        margin: getPxFromStringOrNumber(margin),
        correctLevel,
        maskPattern,
        version,
        components,
        colorDark,
        colorLight,
        autoColor,
        backgroundImage,
        backgroundDimming,
        whiteMargin,
        logoImage,
        logoScale,
        logoMargin: getPxFromStringOrNumber(logoMargin),
        logoCornerRadius: getPxFromStringOrNumber(logoCornerRadius),
        dotScale,
        canvasContainer: { qrMainContainer },
      };

      if (!this.qrDraw) {
        this.qrDraw = new AwesomeQR(option);
      } else {
        this.qrDraw.setOptions(option);
      }
      if (!text) {
        return;
      }
      this.draw();
    },
    getCanvasAndContext(pxSize) {
      return new Promise((reslove, reject) => {
        try {
          const query = uni.createSelectorQuery().in(this)
          query
            .selectAll(".qr-canvas")
            .fields({ node: true, size: true, id: true })
            .exec((res) => {
              const canvasList = res[0].map((item) => {
                const canvas = resetCanvasHeighAndWidth(item.node, pxSize);
                return canvas;
              });
              reslove(canvasList);
            });
        } catch (error) {
          console.error(`${COMPONENT_NAME} 组件获取canvas时报错`, error);
          reject(error);
        }
      });
    },
    draw() {
      this.qrDraw
        .draw()
        .then((rsp) => {
          this.imgSrc = rsp
          this.$emit('load', rsp)
        })
        .catch((err) => {
          console.log(err,'errrrrrrr');
          this.$emit('error')
        });
    }
  },
  mounted() {
    // watch设置了immediate为true后（第一次变化就会触发回调），就不需要this.render了。 
    // this.render()
  }
}
</script>
<style>
.full-w-h {
  height: 100%;
  width: 100%;
}

.qr-container {
  position: relative;
}

.hide-canvas {
  position: absolute;
  top: 0;
  right: 0;
  opacity: 0;
  height: 0;
  width: 0;
  z-index: -1;
}
</style>